package com.feizhoutuobang.shapeline.util.htmlparser;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.apache.log4j.Logger;
import org.htmlparser.Tag;
import org.htmlparser.Text;
import org.htmlparser.lexer.PageAttribute;
import org.htmlparser.tags.ImageTag;
import org.htmlparser.visitors.UrlModifyingVisitor;

import com.feizhoutuobang.shapeline.bo.Image;
import com.feizhoutuobang.shapeline.bo.impl.ImageImpl;
import com.feizhoutuobang.shapeline.dao.ImageDao;
import com.feizhoutuobang.shapeline.util.Calendar;
import com.feizhoutuobang.shapeline.util.Guid;
import com.feizhoutuobang.shapeline.util.WebClient;
import com.feizhoutuobang.shapeline.util.image.JpegNetImage;
import com.feizhoutuobang.shapeline.util.image.NetImage;

public class HtmlModifyingVisitor extends UrlModifyingVisitor {
	
	private static final Logger LOG = Logger.getLogger(HtmlModifyingVisitor.class);
	private List<Image> images = new ArrayList<Image>();
	private String base;
	private int maxImageWidth = 0;
	private int maxImageHeight = 0;
	private boolean imageColored = true;
	private String imagePath = "";
	private WebClient webClient;
	private ImageDao imageDao;
	
	public void setWebClient(WebClient webClient) {
		this.webClient = webClient;
	}
	
	public WebClient getWebClient() {
		return webClient;
	}

	public List<Image> getImages() {
		return images;
	}

	public void setImages(List<Image> images) {
		this.images = images;
	}

	public HtmlModifyingVisitor(String base) {
		super(base);
		this.base = base;
	}

	public int getMaxImageWidth() {
		return maxImageWidth;
	}

	public void setMaxImageWidth(int maxImageWidth) {
		this.maxImageWidth = maxImageWidth;
	}

	public int getMaxImageHeight() {
		return maxImageHeight;
	}

	public void setMaxImageHeight(int maxImageHeight) {
		this.maxImageHeight = maxImageHeight;
	}

	public boolean isImageColored() {
		return imageColored;
	}

	public void setImageColored(boolean imageColored) {
		this.imageColored = imageColored;
	}

	public String getImagePath() {
		return imagePath;
	}

	public void setImagePath(String imagePath) {
		this.imagePath = imagePath;
	}

	public void visitStringNode(Text stringNode) {
	}
	
	@SuppressWarnings("unchecked")
	public void visitTag(Tag tag) {
		try {
			if (tag instanceof ImageTag) {
				
				Vector<PageAttribute> attrs = tag.getAttributesEx();
				String src = "";
				List<String> toRemove = new ArrayList<String>();
				for (PageAttribute attr : attrs) {
					if (attr == null || attr.getName() == null) {
						continue;
					}
					
					if (attr.getName().toLowerCase().equals("src")) {
						src = attr.getValue();
					}
					else if (!attr.getName().toLowerCase().equals("img")) {
						toRemove.add(attr.getName());
					}
				}
				
				for (String attrName : toRemove) {
					tag.removeAttribute(attrName);
				}
				
				if (!src.startsWith("http://") && !src.startsWith("https://")) {
					URL url = new URL(new URL(base), src);
					src = url.toString();
				}
				
				String id = Guid.newId();
				String path = imagePath + File.separatorChar + id + ".jpg";
				
				//download image from src
				try {
					Image image = getImageDao().getImageBySrc(src);
					if (image == null) {
						LOG.info("download image: " + src);
						NetImage ni = new JpegNetImage();
						ni.setWebClient(getWebClient());
						ni.setColored(imageColored);
						ni.setMaxHeight(maxImageHeight);
						ni.setMaxWidth(maxImageWidth);
						File file = ni.getImageFromUrl(src, path);
						LOG.debug("downloaded");
					
						image = new ImageImpl();
						image.setFetchTime(Calendar.now());
						image.setId(id);
						image.setImage(file);
						image.setSrc(src);
						getImageDao().insertImage(image);
					}
					if (!images.contains(image)) {
						images.add(image);
					}
					
					tag.setAttribute("src", "./image/" + id + ".jpg");
				}
				catch (Exception e) {
					tag.setTagName("noimg");
				}
			}
		}
		catch (Exception e) {
			LOG.warn("Modify url failed.", e);
		}
	}

	public void setImageDao(ImageDao imageDao) {
		this.imageDao = imageDao;
	}

	public ImageDao getImageDao() {
		return imageDao;
	}
}
